<?php
namespace Pinenut;

use Pinenut\Model\Finder;
use Pinenut\Model\Updater;

abstract class Model extends \Pinenut\Model\Embedded {
	
	public $_id;
	
	/**
	 * Кеш типов всех полей по моделям
	 * @var unknown_type
	 */
	protected static $_fieldTypes = array();
	
	static function fields() {
		return array('_id'=>static::ID,);
	}
	
	static function getFieldType($field) {
		$class = get_called_class();
		
		if (!isset(static::$_fieldTypes[$class])) 
			static::$_fieldTypes[$class] = static::getFieldTypes(); 
	
		
		if (isset(static::$_fieldTypes[$class][$field])) 
			return static::$_fieldTypes[$class][$field];
	}
	
	
	/**
	 * @param unknown_type $id
	 * @param bool $active
	 * @return \Pinenut\Model|\Pinenut\Model\Finder
	 */
	public static function find($id = null, $active = false) {
		$finder = new Finder(get_called_class());
		$finder->active($active);
		if (null !== $id) {
			return $finder->where('_id', $id)
					->one();
		}
		return $finder;
	}
	
	
	/**
	 * Собираем и выполняем запрос на выборку данных
	 * 
	 * @param array $where
	 * @param array $fields
	 * @return array
	 */
	abstract static function select(array $where = null, 
							array $fields = null, array $order = null, 
							$offset = null, $limit = null);
							
							
	/**
	 * Выполняем запрос на обновление
	 * 
	 * @param array $where
	 * @param array $operators
	 */
	abstract static function update(array $where = null, array $operators = null);
	
	
	/**
	 * Возвращаем кол-во записей по условию
	 * 
	 * @param array $where
	 * @returnint
	 */
	abstract static function count(array $where = null);
	
	/**
	 * Сохраняем/создаем запись целиком
	 */
	abstract public function save();
	
	/** 
	 * Некий хак, позволяющий использовать не статический метод как статический в данном случае для базового класса модели
	 * @see Pinenut\Model.Embedded::modify()
	 */
	public function modify() {
		$updater = new Updater(get_called_class());
		if (isset($this))
			$updater->where('_id', $this->_id);
		
		return $updater;
	}
	
	
	public function getModel() {
		return $this;
	}
	
	public function getFullFieldName() {
		return;
	}
	
	public function __toString() {
		return (string)$this->_id;
	}
}